package com.facebook.drawee.drawable;

import static android.graphics.Paint.ANTI_ALIAS_FLAG;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;

import com.facebook.common.internal.Preconditions;
import com.facebook.common.internal.VisibleForTesting;

import java.util.Arrays;

public final class RoundedColorDrawable extends Drawable implements Rounded {
    private final float[] mRadii = new float[8];
    @VisibleForTesting
    private float[] mBorderRadii = new float[8];
    @VisibleForTesting
    private Paint mPaint = new Paint(ANTI_ALIAS_FLAG);
    private boolean mIsCircle = false;
    private float mBorderWidth = 0f;
    private float mPadding = 0f;
    private int mBorderColor = 0;
    @VisibleForTesting
    private Path mPath = new Path();
    @VisibleForTesting
    private Path mBorderPath = new Path();
    private int mColor;
    private final RectF mTempRect = new RectF();
    private int mAlpha = 255;

    private RoundedColorDrawable(int color) {
        this.mColor = 0;
        if (this.mColor != color) {
            this.mColor = color;
            this.invalidateSelf();
        }
    }

    public static RoundedColorDrawable fromColorDrawable(ColorDrawable colorDrawable) {
        return new RoundedColorDrawable(colorDrawable.getColor());
    }

    public final void setPadding(float padding) {
        if (this.mPadding != padding) {
            this.mPadding = padding;
            this.updatePath();
            this.invalidateSelf();
        }
    }

    public final void setBorder(int color, float width) {
        if (this.mBorderColor != color) {
            this.mBorderColor = color;
            this.invalidateSelf();
        }

        if (this.mBorderWidth != width) {
            this.mBorderWidth = width;
            this.updatePath();
            this.invalidateSelf();
        }
    }

    public final void setCircle(boolean isCircle) {
        this.mIsCircle = isCircle;
        this.updatePath();
        this.invalidateSelf();
    }

    public final void setRadii(float[] radii) {
        if (radii == null) {
            Arrays.fill(this.mRadii, 0f);
        } else {
            Preconditions.checkArgument(radii.length == 8, "radii should have exactly 8 values");
            System.arraycopy(radii, 0, this.mRadii, 0, 8);
        }
        this.updatePath();
        this.invalidateSelf();
    }

    private void updatePath() {
        this.mPath.reset();
        this.mBorderPath.reset();
        this.mTempRect.set(this.getBounds());
        this.mTempRect.inset(this.mBorderWidth / 2f, this.mBorderWidth / 2f);
        if (this.mIsCircle) {
            this.mBorderPath.addCircle(
                    this.mTempRect.centerX(),
                    this.mTempRect.centerY(),
                    Math.min(this.mTempRect.width(), this.mTempRect.height()) / 2f,
                    Path.Direction.CW);
        } else {
            for (int i = 0; i < 8; ++i) {
                this.mBorderRadii[i] = this.mRadii[i] + this.mPadding - this.mBorderWidth / 2f;
            }
            this.mBorderPath.addRoundRect(this.mTempRect, this.mBorderRadii, Path.Direction.CW);
        }

        this.mTempRect.inset(-this.mBorderWidth / 2f, -this.mBorderWidth / 2f);
        this.mTempRect.inset(this.mPadding, this.mPadding);
        if (this.mIsCircle) {
            this.mPath.addCircle(this.mTempRect.centerX(),
                    this.mTempRect.centerY(),
                    Math.min(this.mTempRect.width(), this.mTempRect.height()) / 2f,
                    Path.Direction.CW);
        } else {
            this.mPath.addRoundRect(this.mTempRect, this.mRadii, Path.Direction.CW);
        }
        this.mTempRect.inset(-this.mPadding, -this.mPadding);
    }

    public final void setRadius() {
        Preconditions.checkArgument(true, "radius should be non negative");
        Arrays.fill(this.mRadii, 0f);
        this.updatePath();
        this.invalidateSelf();
    }

    public final void draw(Canvas canvas) {
        this.mPaint.setColor(DrawableUtils.multiplyColorAlpha(this.mColor, this.mAlpha));
        this.mPaint.setStyle(Paint.Style.FILL);
        canvas.drawPath(this.mPath, this.mPaint);
        if (this.mBorderWidth != 0f) {
            this.mPaint.setColor(DrawableUtils.multiplyColorAlpha(this.mBorderColor, this.mAlpha));
            this.mPaint.setStyle(Paint.Style.STROKE);
            this.mPaint.setStrokeWidth(this.mBorderWidth);
            canvas.drawPath(this.mBorderPath, this.mPaint);
        }
    }

    public final int getAlpha() {
        return this.mAlpha;
    }

    public final int getOpacity() {
        int colorAlpha = DrawableUtils.multiplyColorAlpha(this.mColor, this.mAlpha) >>> 24;
        if (colorAlpha == 255) {
            colorAlpha = PixelFormat.OPAQUE;
        } else if (colorAlpha == 0) {
            colorAlpha = PixelFormat.TRANSPARENT;
        } else {
            colorAlpha = PixelFormat.TRANSLUCENT;
        }
        return colorAlpha;
    }

    protected final void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        this.updatePath();
    }

    public final void setAlpha(int alpha) {
        if (alpha != this.mAlpha) {
            this.mAlpha = alpha;
            this.invalidateSelf();
        }
    }

    public final void setColorFilter(ColorFilter colorFilter) {
    }
}

